#!/bin/bash
#
# Update a doctor's root filesystem image. We only extract files with an
# entry in the md5sums.gz list, and we will re-create the checksums on
# completion.
#

[ -d scripts ] || { echo "Run the script from the repacker directory, not the scripts directory" ; exit ; }

if [ $# -gt 0 ]; then ORIGINAL="$1"; else ORIGINAL="original.jar"; fi

MAKE="make"
JAVA="java"
TAR="tar"
JAR="jar"
GZIP="gzip"
SED="sed"
GREP="grep"
TEE="tee"
MD5SUM="md5sum"
BASENAME="basename"
DIRNAME="dirname"
STAT="stat"
BC="bc"

case "`uname -s`" in
    "CYGWIN"* )
	echo "Using Cygwin on Windows is not a valid MetaDoctor option.  See the Wiki page and use WUBI instead."
	exit
	;;
    "Darwin" )
	export COPYFILE_DISABLE=true
	export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
	;;
esac

# Make sure original doctor exists.
if [ ! -f ${ORIGINAL} ]
then
    echo "Can't find source: ${ORIGINAL}"
    echo "Try to specify a file name on the command line."
    exit
fi

# Make sure prerequisites exist.
for f in $MAKE $JAVA $TAR $JAR $GZIP $SED $GREP $TEE $MD5SUM $BASENAME $DIRNAME $STAT $BC ; do

    which $f > /dev/null || { echo "Cannot find $f.  Please install it." ; exit ; }

done

PRESET=$(${BASENAME} $(pwd))
PACKAGE="webOS.tar"
SOURCES="usr etc lib sbin boot bin var dspbridge md5sums.gz"

if [ ! -f build/${PRESET}.jar ]
then
    # Prepare staging area.
    mkdir -p build || exit
    cp ${ORIGINAL} build/${PRESET}.jar || exit
    ( cd build && ${JAR} -xf ${PRESET}.jar META-INF ) || exit
    ( cd build && ${JAR} -xf ${PRESET}.jar resources/${PACKAGE} ) || exit
fi

WEBOS=build/webOS
if [ ! -d ${WEBOS} ]
then
    # Unpack the system resources.
    mkdir -p ${WEBOS} || exit
    ( cd ${WEBOS} && ${TAR} -f ../resources/${PACKAGE} -x ) || exit
fi

ROOT=$(${BASENAME} $(ls ${WEBOS}/*.rootfs.tar.gz))
if [ ! -f ${ROOT%.gz} ]; then ${GZIP} -d ${WEBOS}/${ROOT} || exit; fi

ROOTFS=build/rootfs
if [ ! -d "${ROOTFS}" -o ! -f build/infiles ]
then
    # Unpack the root filesystem and generate file listings.
    mkdir -p "${ROOTFS}" || exit
    ${TAR} -C "${ROOTFS}" -f ${WEBOS}/${ROOT%.gz} -x ./md5sums.gz || exit
    ( cd ${ROOTFS} && zcat md5sums.gz | ${TEE} md5sums | ${SED} 's/^[^\*]*\*//' ) > build/infiles || exit
    ${TAR} -C "${ROOTFS}" -f ${WEBOS}/${ROOT%.gz} -x -T build/infiles || exit

    # Apply patches (only once).
    for i in patches/*.patch
    do
        cat "${i}" | ( cd ${ROOTFS} && patch -p1 ) || exit
    done
fi

# Clear out pre-installed IPK data.
IPKPATH="${ROOTFS}/usr/palm/ipkgs"
rm -f "${IPKPATH}"/*

# Overlay files.
cp -vdpR files/* "${ROOTFS}"

# Update pre-installed application listing and checksums.
IPKGINFO=${ROOTFS}/usr/lib/ipkg/info
LISTING="${IPKGINFO}/app-ipkgs.list"
SUMS="${IPKGINFO}/app-ipkgs.md5sums"
${SED} -i '/^\/usr\/palm\/ipkgs\/.*$/d' ${LISTING}
for i in `cd ${IPKPATH} && ls`
do
    echo "/usr/palm/ipkgs/${i}" >> ${LISTING}
done
rm -f ${SUMS}
for i in `cat ${LISTING}`
do
    ( cd ${ROOTFS} && ${MD5SUM} -b ".${i}" ) >> ${SUMS}
done

# Run any custom filesystem changes.
if [ -x adjust.sh ]
then
    sh adjust.sh "${ROOTFS}"
fi

# Now we need to compare the filesystem files with the files listed in the
# IPK listings. Any extra files should go into a catch-all package to satisfy
# 'integcheck'. Note that 'integcheck' ignores certain files (usually stuff in
# '/var' and the '/usr/lib/ipkg' directory itself, plus some files in '/etc').
PACKNAME="image-extras-cust"
rm -f build/workfiles build/md5files
cat ${IPKGINFO}/*.md5sums | ${GREP} -h -o '\./.*' | sort | uniq > build/md5files
( cd ${ROOTFS} && find . -type f ) | ${GREP} -v '^\.\(/md5sums\|/usr/lib/ipkg\)' > build/workfiles

# Reference additional files (not in original listing) in a special package.
SIZE=0
for i in `sort build/infiles build/infiles build/md5files build/md5files build/workfiles | uniq -u`
do
    echo ${i} | sed 's/^\.\//\//' >> ${IPKGINFO}/${PACKNAME}.list
    ( cd ${ROOTFS} && ${MD5SUM} -b ${i} ) >> ${IPKGINFO}/${PACKNAME}.md5sums

    SIZE=$(cd ${ROOTFS} && echo ${SIZE} + $(${STAT} -c%s "${i}") | ${BC})
    echo "New (${SIZE}): ${i}"
done

# The NEED value just pads SIZE by 25%.
NEED=`echo "${SIZE} * 5 / 4" | ${BC}`
if [ ${SIZE} -gt 0 ]
then
    sed -i "s/^\(InstalledSize:\).*/\1 ${SIZE}/" ${IPKGINFO}/${PACKNAME}.control
    sed -i "s/^\(InstalledSize-rootfs:\).*/\1 ${NEED}/" ${IPKGINFO}/${PACKNAME}.control
fi

# Recalculate every IPKG's MD5 checksums.
./scripts/getmd5.pl ${ROOTFS} . > build/md5sums
for i in ${IPKGINFO}/*.md5sums
do
    ./scripts/replace-md5sums.py "$i" build/md5sums > build/ipkg.md5sums
    if [ $? -gt 0 ]
    then
        mv build/ipkg.md5sums "$i"
    else
        rm -f build/ipkg.md5sums
    fi
done

# Recalculate MD5 checksums of root.
for i in ${ROOTFS}/md5sums*
do
    rm -f $i
done
scripts/getmd5.pl ${ROOTFS} . | ${TEE} build/md5sums | ${SED} 's/^[^\*]*\*//' > build/outfiles
${GZIP} -c build/md5sums > ${ROOTFS}/md5sums.gz

# Repack the root filesystem with updated files.
${TAR} -C ${ROOTFS} -f ${WEBOS}/${ROOT%.gz} --delete -T build/infiles
${TAR} -C ${ROOTFS} -f ${WEBOS}/${ROOT%.gz} --numeric-owner --owner=0 --group=0 -r -T build/outfiles ./md5sums.gz
#${TAR} -C ${ROOTFS} -f ${WEBOS}/${ROOT%.gz} --numeric-owner --owner=0 --group=0 -r ${ROOTFS}/md5sums.gz
${GZIP} -f ${WEBOS}/${ROOT%.gz}
( cd build/webOS && ${TAR} -f ../resources/${PACKAGE} --numeric-owner --owner=0 --group=0 -h -c . )

# Repack the preset jar without hashes and signature.
${SED} -i.orig -e '/^Name: /d' -e '/^SHA1-Digest: /d' -e '/^ /d' -e '/^\n$/d' build/META-INF/MANIFEST.MF
( cd build && zip -q -d ${PRESET}.jar META-INF/MANIFEST.MF META-INF/JARKEY.* resources/${PACKAGE} || true )
( cd build && zip -q ${PRESET}.jar META-INF/MANIFEST.MF resources/${PACKAGE} )

echo
echo "Your custom doctor file has been created at build/${PRESET}.jar"
echo

